package com.jltx.xq.simplewatch.video.model.impl;

import com.jltx.xq.simplewatch.db.helper.NewsRecordDBHelper;
import com.jltx.xq.simplewatch.news.model.bean.NewsRecord;
import com.jltx.xq.simplewatch.news.model.bean.TopicNewsEntity;
import com.jltx.xq.simplewatch.news.model.bean.TopicNewsVideoResponse;
import com.jltx.xq.simplewatch.utils.ListUtils;
import com.jltx.xq.simplewatch.video.model.ITopicLocalNewsModel;
import com.jltx.xq.simplewatch.video.model.ITopicNetNewsModel;
import com.jltx.xq.simplewatch.video.model.ITopicNewsModel;

import cn.jltx.utils.XqLog;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;

/**
 * @author jltxseo
 *         Created by junlintianxia on 2017/09/05.
 */

public class TopicNewsModelImpl implements ITopicNewsModel,ITopicLocalNewsModel,ITopicNetNewsModel{

    public static final String TAG = "TopicNewsModelImpl";

    private TopicNewsLocalModelImpl topicNewsLocalModel;
    private TopicNewsNetModelImpl topicNewsNetModel;

    public TopicNewsModelImpl() {
        topicNewsLocalModel = new TopicNewsLocalModelImpl();
        topicNewsNetModel = new TopicNewsNetModelImpl();
    }

    @Override
    public Observable<TopicNewsEntity> getTopicNews(String channel, boolean isDown) {
        Observable<TopicNewsEntity> observable = null;
        if(topicNewsLocalModel.isHadCacheNewsRecord()){ //判断是否页面第一次加载数据
            if (isDown) {  //下拉去网络获取新闻数据
                observable = getNetTopicNews(channel, isDown);
            } else {  //上拉加载数据库缓存的上一页的数据
                observable = getLocalTopicNews(channel, isDown);
            }
        }else {
            observable = getConcatLocalAndNetTopicNews(channel,isDown);
        }
        return observable;
    }

    @Override
    public boolean isHadCacheNewsRecord() {
        return topicNewsLocalModel.isHadCacheNewsRecord() || topicNewsNetModel.isHadCacheNewsRecord();
    }

    /**
     * 获取网络的数据
     * @param channel
     * @param isDown
     * @return
     */
    public Observable<TopicNewsEntity> getNetTopicNews(String channel, boolean isDown) {
        return topicNewsNetModel.getTopicNews(channel,isDown)
                .observeOn(Schedulers.io())
                .doOnNext(new Consumer<TopicNewsEntity>() {
                    @Override
                    public void accept(@NonNull TopicNewsEntity topicNewsEntity) throws Exception {
                        XqLog.d(TopicNewsModelImpl.TAG,"保存网络新闻数据"+Thread.currentThread());
                        int lastMaxPage = 0;
                        if(!topicNewsNetModel.isHadCacheNewsRecord()){
                            topicNewsNetModel.setLastMaxPageNewsRecord(0);
                            NewsRecord newsRecord = NewsRecordDBHelper.getLastNewsRecord(channel); //根据频道名获取上一次page为最大页面的新闻数据
                            if(newsRecord != null && newsRecord.getPage() > 0){
                                lastMaxPage = newsRecord.getPage();
                                XqLog.d(TopicNewsModelImpl.TAG,"同步最大的页码到NetModel=>"+newsRecord.getPage());
                                topicNewsNetModel.setLastMaxPageNewsRecord(newsRecord.getPage());
                            }
                        }else {
                            lastMaxPage = topicNewsNetModel.getLastMaxPageNewsRecord();
                        }

                        if(!ListUtils.isEmpty(topicNewsEntity.new_list)){
                            XqLog.d(TopicNewsModelImpl.TAG,"新闻页码增加到"+(lastMaxPage + 1));
                            topicNewsNetModel.setLastMaxPageNewsRecord(lastMaxPage + 1);
                            saveWeChatNews(channel,lastMaxPage + 1,topicNewsEntity);
                        }else {
                            XqLog.d(TopicNewsModelImpl.TAG,"从网络获取不到新的新闻");
                        }

                    }
                });
    }

    /**
     * 获取数据库缓存的数据
     * @param channel
     * @param isDown
     * @return
     */
    public Observable<TopicNewsEntity> getLocalTopicNews(String channel, boolean isDown){
        return topicNewsLocalModel.getTopicNews(channel, isDown);
    }

    /**
     * 优先到数据库取新闻数据，取不到再去网络取数据
     * @param channel
     * @param isDown
     * @return
     */
    public Observable<TopicNewsEntity> getConcatLocalAndNetTopicNews(String channel, boolean isDown) {
        //concat()操作符持有多个Observable对象，并将它们按顺序串联成队列。 first()操作符只从串联队列中取出并发送第一个事件。
        //因此，如果使用concat().first()，无论多少个数据源，只有第一个事件会被检索出并发送
        //实现先去本地数据库取数据，取到数据就获取这第一个数据，如果取到本地数据库的数据是空的就去网络获取数据，
        // 网络还是获取不到数据时最后默认返回first里面的默认空List
        return Observable.concat(getLocalTopicNews(channel,isDown),getNetTopicNews(channel,isDown))
                .filter(new Predicate<TopicNewsEntity>() {
                    @Override
                    public boolean test(@NonNull TopicNewsEntity topicNewsEntity) throws Exception {
                        if(topicNewsEntity != null && !ListUtils.isEmpty(topicNewsEntity.new_list)){
                            return true;
                        }
                        return false;
                    }
                })
                .first(new TopicNewsEntity())
                .toObservable()
                .observeOn(Schedulers.io())
                .doOnNext(new Consumer<TopicNewsEntity>() {
                    @Override
                    public void accept(@NonNull TopicNewsEntity topicNewsEntity) throws Exception {
                        XqLog.d(TAG,"策略后得到的新闻数据"+Thread.currentThread());
                        if(!topicNewsNetModel.isHadCacheNewsRecord()){
                            topicNewsNetModel.setLastMaxPageNewsRecord(0);
                            NewsRecord newsRecord = NewsRecordDBHelper.getLastNewsRecord(channel); //根据频道名获取上一次page为最大页面的新闻数据
                            if(newsRecord != null && newsRecord.getPage() > 0){
                                XqLog.d(TAG,"同步最大的页码到NetModel=>"+newsRecord.getPage());
                                topicNewsNetModel.setLastMaxPageNewsRecord(newsRecord.getPage());
                            }
                        }
                    }
                });
    }


    @Override
    public Integer getLastNewsRecordPage() {
        return topicNewsLocalModel.getLastNewsRecordPage();
    }

    @Override
    public void saveWeChatNews(String channel, int page, TopicNewsEntity topicNewsEntity) {
        topicNewsNetModel.saveWeChatNews(channel,page,topicNewsEntity);
    }

    @Override
    public Observable<TopicNewsVideoResponse> getTopicNewsVideoPath(String srcUrl) {
        return topicNewsNetModel.getTopicNewsVideoPath(srcUrl);
    }

    @Override
    public Observable<Integer> updateNewsState(String channel, String key, int isRead, int isDel) {
        return topicNewsLocalModel.updateNewsState(channel,key,isRead,isDel);
    }
}
